
#ifndef RTTHREADTASK_H
#define RTTHREADTASK_H

#include "RtThread.h"
#include "RtEventQueueBase.h"
#include "RtUtilClasses.h"
//#include "RtObserver.h"

class CRtTimerQueueBase;
class CRtTimeValue;

template <class QueueType>
class CRtEventStopT : public IRtEvent
{
public:
	CRtEventStopT(QueueType *aQueue)
		: m_pQueue(aQueue)
	{
		RT_ASSERTE(m_pQueue);
	}

	virtual ~CRtEventStopT()
	{
	}
	
	virtual RtResult OnEventFire()
	{
		if (m_pQueue)
			m_pQueue->SetStopFlag();
		return RT_OK;
	}

	static RtResult PostStopEvent(QueueType *aQueue)
	{
		CRtEventStopT<QueueType> *pEvent = new CRtEventStopT<QueueType>(aQueue);
		if (!pEvent)
			return RT_ERROR_OUT_OF_MEMORY;
		return aQueue->GetEventQueue()->PostEvent(pEvent);
	}

private:
	QueueType *m_pQueue;
};

class RT_API_EXPORT CRtEventQueueUsingConditionVariable
	: public CRtEventQueueBase 
{
public:
	CRtEventQueueUsingConditionVariable();
	virtual ~CRtEventQueueUsingConditionVariable();

	// interface IRtEventQueue
	virtual RtResult PostEvent(IRtEvent *aEvent, EPriority aPri = EPRIORITY_NORMAL);

	// Pop <aMaxCount> pending events in the queue, 
	// if no events are pending, wait <aTimeout>.
	RtResult PopOrWaitPendingEvents(
		CRtEventQueueBase::EventsType &aEvents, 
		CRtTimeValue *aTimeout = NULL,
		DWORD aMaxCount = MAX_GET_ONCE);

private:
	typedef CRtMutexThread MutexType;
	MutexType m_Mutex;
	CRtConditionVariableThread m_Condition;
};

class RT_API_EXPORT CRtThreadTaskWithEventQueueOnly 
	: public CRtThread
	, public CRtStopFlag
{
public:
	CRtThreadTaskWithEventQueueOnly();
	virtual ~CRtThreadTaskWithEventQueueOnly();

	// interface CRtThread
	virtual RtResult Stop(CRtTimeValue* aTimeout = NULL);
	virtual void OnThreadInit();
	virtual void OnThreadRun();
	virtual IRtEventQueue* GetEventQueue();

protected:
	CRtEventQueueUsingConditionVariable m_EventQueue;

	friend class CRtEventStopT<CRtThreadTaskWithEventQueueOnly>;
};

class CRtThreadTask : public CRtThreadTaskWithEventQueueOnly
{
public:
	CRtThreadTask();
	virtual ~CRtThreadTask();

	// interface CRtThread
	virtual void OnThreadInit();
	virtual void OnThreadRun();
	virtual IRtTimerQueue* GetTimerQueue();

protected:
	CRtTimerQueueBase *m_pTimerQueue;
};


class CRtThreadHeartBeat : public CRtThread
{
public:
	CRtThreadHeartBeat();
	virtual ~CRtThreadHeartBeat();

	// interface CRtThread
	virtual RtResult Stop(CRtTimeValue* aTimeout = NULL);
	virtual void OnThreadInit();
	virtual void OnThreadRun();
	virtual IRtEventQueue* GetEventQueue();
	virtual IRtTimerQueue* GetTimerQueue();

	RtResult DoHeartBeat();

protected:
	CRtEventQueueUsingMutex m_EventQueue;
	CRtTimerQueueBase *m_pTimerQueue;
};

#endif // !RTTHREADTASK_H
